package plugins

import (
	"database/sql"
	"errors"
	"reflect"
	"time"
)

// 反射判断接口传参是否根据要求合规
func CheckQuery(param interface{}) (bool, error) {
	if reflect.TypeOf(param).Kind() == reflect.Struct {
		// 获取结构体的值的反射对象
		t := reflect.TypeOf(param)
		v := reflect.ValueOf(param)
		// 遍历结构体的字段
		for i := 0; i < t.NumField(); i++ {
			field := t.Field(i)
			value := v.Field(i).Interface()
			warning := field.Tag.Get("warning")
			// fmt.Printf("%s: %v \n", field.Name, value)
			if v, ok := value.(string); ok {
				if StringIsEmpty(v) && !StringIsEmpty(warning) {
					return false, errors.New(warning)
				}
			}
		}
	}
	return true, nil
}

func IsEmpty(v interface{}) bool {
	if v == nil {
		return true
	}

	_, ok := v.(sql.NullInt64)
	if ok {
		return v.(sql.NullInt64).Valid
	}
	rv := reflect.ValueOf(v)
	if rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			return true
		}
		rv = rv.Elem()
	}

	switch rv.Kind() {
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
		return rv.Len() == 0
	case reflect.Struct:
		if t, ok := v.(time.Time); ok {
			return t.IsZero()
		}
		return reflect.DeepEqual(v, reflect.Zero(rv.Type()).Interface())
	default:
		return rv.IsZero()
	}
}

// 反射判断接口传参是否根据要求合规
func CheckQueryV2(param interface{}) (bool, error) {
	if reflect.TypeOf(param).Kind() == reflect.Struct {
		// 获取结构体的值的反射对象
		t := reflect.TypeOf(param)
		v := reflect.ValueOf(param)
		// 遍历结构体的字段
		for i := 0; i < t.NumField(); i++ {
			field := t.Field(i)
			value := v.Field(i).Interface()
			binding := field.Tag.Get("binding")
			isNeedCheck := (binding == "required")
			// fmt.Printf("%s: %v \n", field.Name, value)
			if isNeedCheck && IsEmpty(value) {
				return false, errors.New("请传入" + field.Name)
			}
		}
	}
	return true, nil
}
